#include "cx_task_message_commond.h"

/*
 *int cx_task_message_callback_handler(CX_MSG_CALLBACK_T *callback_info)
 *{
 *    if(!callback_info)
 *    {
 *        return -EINVAL;
 *    }
 *#if (CX_CPU_ARCH == CX_CPU_ARCH_RV32)
 *    if(callback_info->function_params_num > 8)
 *    {
 *        return -EOVERFLOW;
 *    }
 *#endif
 *    return 0;
 *}
 */


__attribute__((naked)) // 避免额外栈帧处理
static int cx_task_message_callback(CX_MSG_CALLBACK_T *callback_info) {
#if (CX_CPU_ARCH == CX_CPU_ARCH_RV32)
    asm volatile (
        // ============= 参数校验阶段 ================
        "beqz a0, fail_invalid\n"             // 空指针检查
        "lw   t0, 4(a0)\n"                   // t0 = function_params_num
        "li   t1, 8\n"
        "bgtu t0, t1, fail_overflow\n"        // 参数数量检查(最大8)
        
        // ============= 寄存器加载阶段 ==============
        "lw   t1, 0(a0)\n"                   // t1 = 函数地址
        "addi a0, a0, 8\n"
        "li   t2, 0\n"                       // 当前加载的寄存器索引
        
        // 寄存器参数加载循环
        "1:\n"
        "beq  t2, t0, 2f\n"                 // 检查是否加载完所有参数
        "slli t3, t2, 2\n"                  // t3 = 偏移量(4*索引)
        "add  t3, a0, t3\n"                 // t3 = 当前参数地址
        "lw   t4, 0(t3)\n"                  // 载入参数值
        
        // 动态选择寄存器
        "li   t5, 0\n"
        "beq  t2, t5, load_a0\n"
        "li   t5, 1\n"
        "beq  t2, t5, load_a1\n"
        "li   t5, 2\n"
        "beq  t2, t5, load_a2\n"
        "li   t5, 3\n"
        "beq  t2, t5, load_a3\n"
        "li   t5, 4\n"
        "beq  t2, t5, load_a4\n"
        "li   t5, 5\n"
        "beq  t2, t5, load_a5\n"
        "li   t5, 6\n"
        "beq  t2, t5, load_a6\n"
        "li   t5, 7\n"
        "beq  t2, t5, load_a7\n"
        
        // 寄存器加载处理块
        "load_a0: mv a0, t4; j 3f\n"
        "load_a1: mv a1, t4; j 3f\n"
        "load_a2: mv a2, t4; j 3f\n"
        "load_a3: mv a3, t4; j 3f\n"
        "load_a4: mv a4, t4; j 3f\n"
        "load_a5: mv a5, t4; j 3f\n"
        "load_a6: mv a6, t4; j 3f\n"
        "load_a7: mv a7, t4; j 3f\n"
        
        // 循环控制
        "3:\n"
        "addi t2, t2, 1\n"                  // 索引++
        "j    1b\n"                         // 继续循环
        
        // ============= 函数调用阶段 ==============
        "2:\n"
        "addi sp, sp, -16\n"                // 保存返回地址
        "sw ra, 12(sp)\n"
        "jalr ra, t1, 0\n"                  // 调用目标函数
        "lw ra, 12(sp)\n"
        "addi sp, sp, 16\n"                 // 恢复返回地址
        
        // ============= 返回结果处理 ==============
        "ret\n"                             // 使用调用函数的返回值直接返回
        
        // ============= 错误处理路径 =============
        "fail_invalid:\n"
        "li   a0, %[einval]\n"              // -EINVAL
        "ret\n"
        
        "fail_overflow:\n"
        "li   a0, %[eoverflow]\n"           // -EOVERFLOW
        "ret\n"

        
        // 编译器约束
        : 
        : [einval] "i" (-EINVAL),
          [eoverflow] "i" (-EOVERFLOW)
        : "t0", "t1", "t2", "t3", "t4", "t5", "memory"
    );
#endif
}

int cx_task_messaage_callback_handler(CX_MSG_CALLBACK_T *msg)
{
    return cx_task_message_callback(msg);
}
